package com.gitee.qdbp.general.system.api.permission.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.gitee.qdbp.able.jdbc.paging.PartList;
import com.gitee.qdbp.base.annotation.DataIsolation;
import com.gitee.qdbp.base.annotation.OperateTraces;
import com.gitee.qdbp.base.enums.DataState;
import com.gitee.qdbp.base.system.model.IResource;
import com.gitee.qdbp.general.system.enums.SysResState;
import com.gitee.qdbp.general.system.enums.SysResType;

/**
 * 资源信息实体类
 *
 * @author zhh
 * @version 180514
 */
@OperateTraces(id = "id", code = "key", desc = "name")
@DataIsolation(enable = false)
public class ResourceCoreBean implements IResource, Serializable, Comparable<ResourceCoreBean> {

    /** 版本序列号 **/
    private static final long serialVersionUID = 1L;

    /** 表名 **/
    public static final String TABLE = "sys_resource_core_info";

    /** 资源ID **/
    private String id;

    /** 使用场景 **/
    private String sceneType;

    /** 资源KEY **/
    private String key;

    /** 资源名称 **/
    private String name;

    /** 资源类型(0.模块|1.菜单组|2.菜单|3.操作) **/
    private SysResType type;

    /** 页面地址 **/
    private String url;

    /** 资源选项 **/
    private ResourceOptions options;

    /** 排序号(越小越靠前) **/
    private Integer sortIndex;

    /** 上级资源ID **/
    private String parentId;

    /** 描述 **/
    private String description;

    /** 状态(0.正常|1.禁用) **/
    private SysResState state;

    /** 数据状态:0为正常|其他为删除 **/
    private DataState dataState;

    /** 获取资源ID **/
    public String getId() {
        return id;
    }

    /** 设置资源ID **/
    public void setId(String id) {
        this.id = id;
    }

    /** 获取使用场景 **/
    public String getSceneType() {
        return sceneType;
    }

    /** 设置使用场景 **/
    public void setSceneType(String sceneType) {
        this.sceneType = sceneType;
    }

    /** 获取资源KEY **/
    public String getKey() {
        return key;
    }

    /** 设置资源KEY **/
    public void setKey(String key) {
        this.key = key;
    }

    /** 获取资源名称 **/
    public String getName() {
        return name;
    }

    /** 设置资源名称 **/
    public void setName(String name) {
        this.name = name;
    }

    /** 获取资源类型(0.模块|1.菜单组|2.菜单|3.操作) **/
    public SysResType getType() {
        return type;
    }

    /** 设置资源类型(0.模块|1.菜单组|2.菜单|3.操作) **/
    public void setType(SysResType type) {
        this.type = type;
    }

    /** 获取页面地址 **/
    public String getUrl() {
        return url;
    }

    /** 设置页面地址 **/
    public void setUrl(String url) {
        this.url = url;
    }

    /** 获取资源选项 **/
    public ResourceOptions getOptions() {
        return options;
    }

    /** 获取资源选项, force=是否强制返回非空对象 **/
    public ResourceOptions getOptions(boolean force) {
        if (options == null && force) {
            options = new ResourceOptions();
        }
        return options;
    }

    /** 设置资源选项 **/
    public void setOptions(ResourceOptions options) {
        this.options = options;
    }

    /** 获取排序号(越小越靠前) **/
    public Integer getSortIndex() {
        return sortIndex;
    }

    /** 设置排序号(越小越靠前) **/
    public void setSortIndex(Integer sortIndex) {
        this.sortIndex = sortIndex;
    }

    /** 获取上级资源ID **/
    public String getParentId() {
        return parentId;
    }

    /** 设置上级资源ID **/
    public void setParentId(String parentId) {
        this.parentId = parentId;
    }

    /** 获取描述 **/
    public String getDescription() {
        return description;
    }

    /** 设置描述 **/
    public void setDescription(String description) {
        this.description = description;
    }

    /** 获取状态(0.正常|1.禁用) **/
    public SysResState getState() {
        return state;
    }

    /** 设置状态(0.正常|1.禁用) **/
    public void setState(SysResState state) {
        this.state = state;
    }

    /** 获取数据状态:0为正常|其他为删除 **/
    public DataState getDataState() {
        return dataState;
    }

    /** 设置数据状态:0为正常|其他为删除 **/
    public void setDataState(DataState dataState) {
        this.dataState = dataState;
    }

    /**
     * 将当前对象转换为子类对象
     *
     * @param clazz 目标类型
     * @return 目标对象
     */
    public <T extends ResourceCoreBean> T to(Class<T> clazz) {
        T instance;
        try {
            instance = clazz.newInstance();
        } catch (Exception e) {
            throw new IllegalArgumentException("Failed to create " + clazz.getSimpleName() + " instance.", e);
        }

        instance.setId(this.getId()); // 资源ID
        instance.setSceneType(this.getSceneType()); // 使用场景
        instance.setKey(this.getKey()); // 资源KEY
        instance.setName(this.getName()); // 资源名称
        instance.setType(this.getType()); // 资源类型(0.模块|1.菜单组|2.菜单|3.操作)
        instance.setUrl(this.getUrl()); // 页面地址
        instance.setOptions(this.getOptions()); // 资源选项
        instance.setSortIndex(this.getSortIndex()); // 排序号(越小越靠前)
        instance.setParentId(this.getParentId()); // 上级资源ID
        instance.setDescription(this.getDescription()); // 描述
        instance.setState(this.getState()); // 状态(0.正常|1.禁用)
        instance.setDataState(this.getDataState()); // 数据状态:0为正常|其他为删除
        return instance;
    }

    /**
     * 将ResourceCoreBean转换为子类对象
     *
     * @param beans 待转换的对象列表
     * @param clazz 目标类型
     * @param <T> ResourceCoreBean或子类
     * @param <C> T的子类
     * @return 目标对象列表
     */
    public static <T extends ResourceCoreBean, C extends T> List<C> to(List<T> beans, Class<C> clazz) {
        if (beans == null) {
            return null;
        }
        List<C> list;
        if (beans instanceof PartList) {
            PartList<C> partlist = new PartList<>();
            partlist.setTotal(((PartList<?>) beans).getTotal());
            list = partlist;
        } else {
            list = new ArrayList<>();
        }
        for (ResourceCoreBean bean : beans) {
            list.add(bean.to(clazz));
        }
        return list;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((dataState == null) ? 0 : dataState.hashCode());
        result = prime * result + ((key == null) ? 0 : key.hashCode());
        result = prime * result + ((type == null) ? 0 : type.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        ResourceCoreBean other = (ResourceCoreBean) obj;
        if (dataState != other.dataState) return false;
        if (key == null) {
            if (other.key != null) return false;
        } else if (!key.equals(other.key)) return false;
        if (type != other.type) return false;
        return true;
    }

    @Override
    public String toString() {
        String type = this.type == null ? "" : "[" + this.type + "]";
        if (this.name != null && this.name.length() > 0 && this.key != null && this.key.length() > 0) {
            return type + this.name + "(" + this.key + ")";
        } else if (this.name != null && this.name.length() > 0) {
            return type + this.name;
        } else if (this.key != null && this.key.length() > 0) {
            return type + this.key;
        } else {
            return this.getClass().getSimpleName() + type + "(" + this.id + ")";
        }
    }

    @Override
    public int compareTo(ResourceCoreBean o) {
        SysResType g = SysResType.GROUP;
        SysResType m = SysResType.MENU;
        if (o == null) {
            return 1;
        } else {
            int index;
            if ((this.getType() == g || this.getType() == m) && (o.getType() == g || o.getType() == m)) {
                index = 0; // 菜单组和菜单属于同一级别
            } else {
                index = this.getType().compareTo(o.getType());
            }

            if (index == 0) {
                index = this.getSortIndex().compareTo(o.getSortIndex());
            }
            if (index == 0) {
                index = this.getKey().compareTo(o.getKey());
            }
            return index;
        }
    }

}
